package com.hexingmo.dawn.lang.concurrent;

import com.hexingmo.dawn.lang.Assert;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 命名线程工厂，用于创建具有自定义名称和守护线程状态的线程。
 *
 * <p>该类实现了 {@link ThreadFactory} 接口，可以用于 {@link java.util.concurrent.ExecutorService}
 * 等需要线程工厂的场景。每个创建的线程都会有一个唯一的名称，格式为：{@code namePrefix-threadNumber}。</p>
 *
 * <p><strong>特性：</strong></p>
 * <ul>
 *   <li><strong>自动命名</strong>：线程名称自动递增，确保唯一性</li>
 *   <li><strong>守护线程支持</strong>：可配置是否为守护线程</li>
 *   <li><strong>线程优先级</strong>：可设置线程优先级</li>
 *   <li><strong>异常处理</strong>：可设置未捕获异常处理器</li>
 *   <li><strong>线程安全</strong>：使用原子操作确保线程安全</li>
 * </ul>
 *
 * <p><strong>使用示例：</strong></p>
 * <pre>{@code
 * // 创建基本的命名线程工厂
 * NamedThreadFactory factory = new NamedThreadFactory("worker");
 * ExecutorService executor = Executors.newFixedThreadPool(5, factory);
 *
 * // 创建守护线程工厂
 * NamedThreadFactory daemonFactory = new NamedThreadFactory("daemon-worker", true);
 * ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3, daemonFactory);
 *
 * // 创建高优先级线程工厂
 * NamedThreadFactory highPriorityFactory = new NamedThreadFactory("high-priority", false, Thread.MAX_PRIORITY);
 * ExecutorService highPriorityExecutor = Executors.newSingleThreadExecutor(highPriorityFactory);
 * }</pre>
 *
 * <p><strong>实际应用场景：</strong></p>
 * <ul>
 *   <li><strong>线程池管理</strong>：为不同的线程池创建具有标识性的线程</li>
 *   <li><strong>调试和监控</strong>：通过线程名称快速识别线程用途</li>
 *   <li><strong>日志记录</strong>：在日志中清晰显示线程来源</li>
 *   <li><strong>性能分析</strong>：通过线程名称进行性能分析和问题定位</li>
 *   <li><strong>系统集成</strong>：与监控系统集成，提供线程级别的指标</li>
 * </ul>
 *
 * @author He Xing Mo
 * @since 1.0
 * @see ThreadFactory
 * @see java.util.concurrent.ExecutorService
 * @see java.util.concurrent.Executors
 */
public class NamedThreadFactory implements ThreadFactory {

    /**
     * 线程名称前缀
     */
    private final String namePrefix;

    /**
     * 是否为守护线程
     */
    private final boolean daemon;

    /**
     * 线程优先级
     */
    private final int priority;

    /**
     * 未捕获异常处理器
     */
    private final Thread.UncaughtExceptionHandler exceptionHandler;

    /**
     * 线程计数器，用于生成唯一的线程名称
     */
    private final AtomicInteger threadNumber = new AtomicInteger(1);

    /**
     * 线程组，用于管理创建的线程
     */
    private final ThreadGroup threadGroup;

    /**
     * 使用默认参数创建命名线程工厂。
     *
     * <p>默认参数：</p>
     * <ul>
     *   <li>守护线程：false（非守护线程）</li>
     *   <li>线程优先级：{@link Thread#NORM_PRIORITY}</li>
     *   <li>异常处理器：null（使用默认处理器）</li>
     * </ul>
     *
     * @param namePrefix 线程名称前缀，不能为null或空字符串
     * @throws IllegalArgumentException 如果namePrefix为null或空字符串
     */
    public NamedThreadFactory(String namePrefix) {
        this(namePrefix, false);
    }

    /**
     * 创建命名线程工厂，可指定是否为守护线程。
     *
     * <p>使用默认的线程优先级和异常处理器。</p>
     *
     * @param namePrefix 线程名称前缀，不能为null或空字符串
     * @param daemon 是否为守护线程
     * @throws IllegalArgumentException 如果namePrefix为null或空字符串
     */
    public NamedThreadFactory(String namePrefix, boolean daemon) {
        this(namePrefix, daemon, Thread.NORM_PRIORITY);
    }

    /**
     * 创建命名线程工厂，可指定守护线程状态和线程优先级。
     *
     * <p>使用默认的异常处理器。</p>
     *
     * @param namePrefix 线程名称前缀，不能为null或空字符串
     * @param daemon 是否为守护线程
     * @param priority 线程优先级，范围：{@link Thread#MIN_PRIORITY} 到 {@link Thread#MAX_PRIORITY}
     * @throws IllegalArgumentException 如果namePrefix为null或空字符串，或priority超出有效范围
     */
    public NamedThreadFactory(String namePrefix, boolean daemon, int priority) {
        this(namePrefix, daemon, priority, null);
    }

    /**
     * 创建完整的命名线程工厂，可指定所有参数。
     *
     * @param namePrefix 线程名称前缀，不能为null或空字符串
     * @param daemon 是否为守护线程
     * @param priority 线程优先级，范围：{@link Thread#MIN_PRIORITY} 到 {@link Thread#MAX_PRIORITY}
     * @param exceptionHandler 未捕获异常处理器，可以为null
     * @throws IllegalArgumentException 如果namePrefix为null或空字符串，或priority超出有效范围
     */
    public NamedThreadFactory(String namePrefix, boolean daemon, int priority, Thread.UncaughtExceptionHandler exceptionHandler) {
        // 参数验证
        if (namePrefix == null || namePrefix.trim().isEmpty()) {
            throw new IllegalArgumentException("Thread name prefix cannot be null or empty");
        }
        
        if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
            throw new IllegalArgumentException("Thread priority must be between " + 
                Thread.MIN_PRIORITY + " and " + Thread.MAX_PRIORITY);
        }

        this.namePrefix = namePrefix.trim();
        this.daemon = daemon;
        this.priority = priority;
        this.exceptionHandler = exceptionHandler;
        
        // 创建线程组，使用当前线程的线程组作为父组
        SecurityManager securityManager = System.getSecurityManager();
        this.threadGroup = (securityManager != null) ? 
            securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
    }

    /**
     * 创建并配置新线程。
     *
     * <p>该方法会：</p>
     * <ul>
     *   <li>生成唯一的线程名称</li>
     *   <li>设置守护线程状态</li>
     *   <li>设置线程优先级</li>
     *   <li>设置异常处理器（如果提供）</li>
     *   <li>将线程添加到线程组</li>
     * </ul>
     *
     * @param runnable 要在线程中执行的任务，不能为null
     * @return 配置好的新线程
     * @throws IllegalArgumentException 如果runnable为null
     */
    @Override
    public Thread newThread(Runnable runnable) {
        Assert.notNull(runnable , "runnable cannot be null");

        // 生成唯一的线程名称
        String threadName = generateThreadName();
        
        // 创建新线程
        Thread thread = new Thread(threadGroup, runnable, threadName);
        
        // 配置线程属性
        thread.setDaemon(daemon);
        thread.setPriority(priority);
        
        // 设置异常处理器（如果提供）
        if (exceptionHandler != null) {
            thread.setUncaughtExceptionHandler(exceptionHandler);
        }
        
        return thread;
    }

    /**
     * 生成唯一的线程名称。
     *
     * <p>线程名称格式：{@code namePrefix-threadNumber}</p>
     *
     * @return 唯一的线程名称
     */
    private String generateThreadName() {
        return namePrefix + "-" + threadNumber.getAndIncrement();
    }

    /**
     * 获取线程名称前缀。
     *
     * @return 线程名称前缀
     */
    public String getNamePrefix() {
        return namePrefix;
    }

    /**
     * 检查是否为守护线程工厂。
     *
     * @return 如果创建守护线程返回true，否则返回false
     */
    public boolean isDaemon() {
        return daemon;
    }

    /**
     * 获取线程优先级。
     *
     * @return 线程优先级
     */
    public int getPriority() {
        return priority;
    }

    /**
     * 获取未捕获异常处理器。
     *
     * @return 异常处理器，如果没有设置则返回null
     */
    public Thread.UncaughtExceptionHandler getExceptionHandler() {
        return exceptionHandler;
    }

    /**
     * 获取线程组。
     *
     * @return 线程组
     */
    public ThreadGroup getThreadGroup() {
        return threadGroup;
    }

    /**
     * 获取已创建的线程数量。
     *
     * <p>注意：这个值表示从工厂创建开始的总线程数，包括可能已经结束的线程。</p>
     *
     * @return 已创建的线程数量
     */
    public int getThreadCount() {
        return threadNumber.get() - 1;
    }

    @Override
    public String toString() {
        return "NamedThreadFactory{" +
                "namePrefix='" + namePrefix + '\'' +
                ", daemon=" + daemon +
                ", priority=" + priority +
                ", threadCount=" + getThreadCount() +
                '}';
    }
}
